home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swags_z.zip / TEXTFILE.SWG / 0010_TEXTUNIT.PAS.pas < prev    next >
Pascal/Delphi Source File  |  1993-05-28  |  6KB  |  138 lines

  1. Unit TextUtil;
  2. {        Written by Wilbert Van.Leijen and posted in the Pascal Echo }
  3.  
  4. Interface
  5.  
  6. Function TextFilePos(Var f : Text) : LongInt;
  7. Function TextFileSize(Var f : Text) : LongInt;
  8. Procedure TextSeek(Var f : Text; n : LongInt);
  9.  
  10. Implementation
  11. Uses Dos;
  12.  
  13. {$R-,S- }
  14.  
  15. Procedure GetFileMode; Assembler;
  16.  
  17. Asm
  18.                                 CLC
  19.                                 CMP    ES:[DI].TextRec.Mode, fmInput
  20.                                 JE     @1
  21.                                 MOV    [InOutRes], 104         { 'File not opened For reading' }
  22.                                 xor    AX, AX                  { Zero out Function result }
  23.                                 xor    DX, DX
  24.                                 STC
  25. @1:
  26. end;  { GetFileMode }
  27.  
  28. Function TextFilePos(Var f : Text) : LongInt; Assembler;
  29.  
  30. Asm
  31.         LES    DI, f
  32.         CALL   GetFileMode
  33.         JC     @1
  34.  
  35.         xor    CX, CX                  { Get position of File Pointer }
  36.         xor    DX, DX
  37.         MOV    BX, ES:[DI].TextRec.handle
  38.         MOV    AX, 4201h
  39.         inT    21h                     { offset := offset-Bufend+BufPos }
  40.                                 xor    BX, BX
  41.         SUB    AX, ES:[DI].TextRec.Bufend
  42.         SBB    DX, BX
  43.         ADD    AX, ES:[DI].TextRec.BufPos
  44.         ADC    DX, BX
  45. @1:
  46. end;  { TextFilePos }
  47.  
  48.  
  49. Function TextFileSize(Var f : Text) : LongInt; Assembler;
  50.  
  51. Asm
  52.                                 LES    DI, f
  53.                                 CALL   GetFileMode
  54.                                 JC     @1
  55.  
  56.                                 xor    CX, CX                  { Get position of File Pointer }
  57.         xor    DX, DX
  58.         MOV    BX, ES:[DI].TextRec.handle
  59.         MOV    AX, 4201h
  60.                                 inT    21h
  61.         PUSH   DX                      { Save current offset on the stack }
  62.                                 PUSH   AX
  63.         xor    DX, DX                  { Move File Pointer to Eof }
  64.         MOV    AX, 4202h
  65.         inT    21h
  66.         POP    SI
  67.         POP    CX
  68.                                 PUSH   DX                      { Save Eof position }
  69.         PUSH   AX
  70.         MOV    DX, SI                  { Restore old offset }
  71.         MOV    AX, 4200h
  72.         inT    21h
  73.         POP    AX                      { Return result}
  74.         POP    DX
  75. @1:
  76. end;  { TextFileSize }
  77.  
  78. Procedure TextSeek(Var f : Text; n : LongInt); Assembler;
  79.  
  80. Asm
  81.         LES    DI, f
  82.                                 CALL   GetFileMode
  83.         JC     @2
  84.  
  85.         MOV    CX, Word Ptr n+2        { Move File Pointer }
  86.         MOV    DX, Word Ptr n
  87.         MOV    BX, ES:[DI].TextRec.Handle
  88.                                 MOV    AX, 4200h
  89.                                 inT    21h
  90.                                 JNC    @1                      { Carry flag = reading past Eof }
  91.                                 MOV    [InOutRes], AX
  92.                                 JMP    @2
  93.                                                                                                                                                          { Force read next time }
  94. @1:     MOV    AX, ES:[DI].TextRec.Bufend
  95.                                 MOV    ES:[DI].TextRec.BufPos, AX
  96. @2:
  97. end;  { TextSeek }
  98. end.  { TextUtil }
  99.  
  100. {    With the aid of that Unit you could save the position of each line
  101. in the Text File to an Array of LongInt as you read them. You can also
  102. open a temporary File, a File of LongInt, where each Record would simply
  103. represent the offset of that line in the Text File. if you need to go
  104. back in the Text, simply read the offset of the line where you which to
  105. restart reading. Suppose you are on line 391 and you decide to go back
  106. say, 100 lines, simply do a Seek(MyIndex, CurrentLine-100). then use the
  107. TextSeek Procedure to seek to that position in the Text File and start
  108. reading again, taking into acount that you allready read those lines so
  109. you either re-Write the offsets to your index File, which won't hurt
  110. since you will just be overwriting the Records With the same values
  111. again or simply skip writing the offsets Until you reach a point where
  112. NEW lines that haven't yet been read are reached. Save any new offset as
  113. you read Forward.
  114.  
  115.     With this method you can go back-wards as well as Forwards. In fact
  116. if you first read the File, saving all offsets Until the end, you can
  117. offer the user to seek to any line number.
  118.  
  119.     When you read new lines or seek backwards, simply flush any lines
  120. from memory. or maybe you could decide to keep a predetermined number of
  121. lines in memory say 300. When ever the user asks to read Forward or
  122. backwards, simply flush the 100 first or Last line, depending on the
  123. direction the user wants to go, and read 100 new lines from the Text
  124. File.
  125.  
  126.     Maybe the best approach to be sure of sufficient memory is to
  127. determine how many lines will fit. Suppose you limit line lengths to 255
  128. caracters. Determine how many will fit in a worse Case scenario. Create
  129. as many 255 caracter Strings as will fit. divide that number of lines by
  130. 4. Say you managed to create 1000 Strings of 255 caracters. divided by 4
  131. is 250. So set a limit to 750 Strings to be safe and make any disk
  132. accesses in bundles of 250 Lines.
  133.  
  134.     You can also keep the line offsets in memory in Arrays but you will
  135. be limited to 65520 / 8 = 16380 lines. Make that two Arrays stored on
  136. the heap and you've got yourself enough space to store 32760 line
  137. offsets which at 255 caracters by line would be an 8.3 Meg File.
  138.  }